package com.zttek.videoShareProject.modules.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zttek.videoShareProject.common.json.HistoryVO;
import com.zttek.videoShareProject.common.json.VideoVO;
import com.zttek.videoShareProject.modules.mapper.AbuseMapper;
import com.zttek.videoShareProject.modules.mapper.FollowMapper;
import com.zttek.videoShareProject.modules.mapper.HistoryMapper;
import com.zttek.videoShareProject.modules.mapper.UserMapper;
import com.zttek.videoShareProject.modules.model.Abuse;
import com.zttek.videoShareProject.modules.model.Follow;
import com.zttek.videoShareProject.modules.model.History;
import com.zttek.videoShareProject.modules.model.User;
import com.zttek.videoShareProject.modules.model.Video;
import com.zttek.videoShareProject.modules.mapper.VideoMapper;
import com.zttek.videoShareProject.modules.service.IFollowService;
import com.zttek.videoShareProject.modules.service.IVideoService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

import static com.zttek.videoShareProject.common.utils.DateUtils.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author CBY
 * @since 2018-07-03
 */
@Service
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements IVideoService {

    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private FollowMapper followMapper;
    @Autowired
    private IFollowService followService;
    @Autowired
    private AbuseMapper abuseMapper;
    @Autowired
    private HistoryMapper historyMapper;

    @Autowired
    IVideoService videoService;

    /**
     * 一次返回3条最新视频数据
     *
     * @return
     * @throws Exception
     */
    @Transactional
    public List<VideoVO.RecentThreeVideo> showRecentVideo() throws Exception {
        Page<Video> page = new Page<Video>(1,3);
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        ew.ne("status",0);
        ew.orderBy("upload_date",false);
        page.setRecords( videoMapper.selectPage(page,ew));//记录page
        List<Video> videos = videoMapper.selectPage(page,ew);
        List<VideoVO.RecentThreeVideo> list = new ArrayList<VideoVO.RecentThreeVideo>();
        for(int i=0;i<page.getRecords().size();i++) {
            VideoVO.RecentThreeVideo recentThreeVideo = new VideoVO.RecentThreeVideo();
            Video nowVideo = videos.get(i);
            if(nowVideo.getStatus()!=0) {
                User nowuser = userMapper.selectById(nowVideo.getUserId());
                //添加前3个视频的信息到VO中
                recentThreeVideo.setVideo_id(nowVideo.getVideoId());
                recentThreeVideo.setImage_url(nowVideo.getImageUrl());
                recentThreeVideo.setTitle(nowVideo.getTitle());
                recentThreeVideo.setTotal_time(Long2String(nowVideo.getTotalTime()));
                recentThreeVideo.setViews(nowVideo.getViews());
                recentThreeVideo.setAccount(nowuser.getAccount());
                list.add(recentThreeVideo);
            }
        }
        return list;
    }

    /**
     * 一次返回1条视频数据
     * @param videoid="当前视频的id" userid="当前登录用户"
     * @return
     * @throws Exception
     */
    @Transactional
    public VideoVO.OneVideo showOneVideo(Long videoid,Long userid) throws Exception{

        VideoVO.OneVideo oneVideo = new VideoVO.OneVideo();
        Video video = videoMapper.selectById(videoid);
        oneVideo.setVideo_id(video.getVideoId());
        oneVideo.setImage_url(video.getImageUrl());
        oneVideo.setVideo_url(video.getVideoUrl());
        oneVideo.setTitle(video.getTitle());
        oneVideo.setIntro(video.getIntro());
        oneVideo.setTotal_time(Long2String(video.getTotalTime()));
        oneVideo.setViews(video.getViews());

        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        video.setViews(video.getViews()+1);
        ew.where("video_id={0}",video.getVideoId());
        videoMapper.update(video,ew);

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(video.getUploadDate());
        oneVideo.setUpload_date(dateString);
        oneVideo.setUser_id(video.getUserId());
        oneVideo.setAccount(userMapper.selectById(video.getUserId()).getAccount());
        oneVideo.setUser_image_url(userMapper.selectById(video.getUserId()).getImageUrl());

        Follow follow = new Follow();
        follow.setFollowerId(userid);
        follow.setFollowId(video.getUserId());
        if(userid==0) {
            oneVideo.setIs_follow(0);
            return oneVideo;
        }else {
            oneVideo.setIs_follow(followService.isFollow(follow));
            return oneVideo;
        }
    }

    /**
     * 返回12个热门上升视频数据
     *
     * @return
     * @throws Exception
     */
    @Transactional
    public List<VideoVO.HotVideo> showHotVideo() throws Exception{
        Page<Video> page = new Page<Video>(1,12);
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        ew.ne("status",0);
        ew.orderBy("views",false);
        page.setRecords( videoMapper.selectPage(page,ew));//记录page
        List<Video> videos = videoMapper.selectPage(page,ew);
        List<VideoVO.HotVideo> list = new ArrayList<VideoVO.HotVideo>();
        for(int i=0;i<page.getRecords().size();i++) {
            VideoVO.HotVideo hotVideo = new VideoVO.HotVideo();
            Video nowVideo = videos.get(i);
            if(nowVideo.getStatus()!=0) {
                User nowuser = userMapper.selectById(nowVideo.getUserId());
                hotVideo.setVideo_id(nowVideo.getVideoId());
                hotVideo.setImage_url(nowVideo.getImageUrl());
                hotVideo.setTitle(nowVideo.getTitle());
                hotVideo.setViews(nowVideo.getViews());
                hotVideo.setAccount(nowuser.getAccount());
                list.add(hotVideo);
            }
        }
        return list;
    }

    /**
     * 一次返回2*4条视频数据
     *
     * @return
     * @throws Exception
     */
    @Transactional
    public List<VideoVO.ShowByVideoType> returnByType(Integer pageNum,String videotype) throws Exception {
        Page<Video> page = new Page<Video>(pageNum,8);
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        ew.where("video_type={0}",videotype);
        ew.ne("status",0);
        ew.orderBy("views",false);
        page.setRecords( videoMapper.selectPage(page,ew));//记录page
        List<Video> videos = videoMapper.selectPage(page,ew);
        List<VideoVO.ShowByVideoType> list = new ArrayList<VideoVO.ShowByVideoType>();
        for(int i=0;i<page.getRecords().size();i++){
            VideoVO.ShowByVideoType showByVideoType = new VideoVO.ShowByVideoType();
            Video video = videos.get(i);
            if(video.getStatus()!=0) {
                showByVideoType.setVideo_id(video.getVideoId());
                showByVideoType.setImage_url(video.getImageUrl());
                showByVideoType.setTitle(video.getTitle());
                showByVideoType.setTotal_time(Long2String(video.getTotalTime()));
                showByVideoType.setViews(video.getViews());
                showByVideoType.setAccount(userMapper.selectById(video.getUserId()).getAccount());
                list.add(showByVideoType);
            }
        }
        return list;
    }

    /**
     * 搜索返回2*4条视频数据
     *
     * @return
     * @throws Exception
     */
    @Transactional
    public List<VideoVO.SearchVideo> SearchVideo(Integer pageNum,String search,String videotype) throws Exception {
        Page<Video> page = new Page<Video>(pageNum,8);
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        EntityWrapper<User> ewuser = new EntityWrapper<User>();
        if(videotype.equals("0")){
           //ew.like("title",search).orderBy("views",false);
            page.setRecords(videoMapper.searchVideo2(search));//记录page
            List<Video> videos = page.getRecords();
            //List<Video> videos = videoMapper.selectPage(page,ew);
            List<VideoVO.SearchVideo> list = new ArrayList<VideoVO.SearchVideo>();
            //ewuser.like("account",search);
            //List<User> users = userMapper.selectList(ewuser);
            for(int i=(pageNum-1)*8;i<(pageNum*8>page.getRecords().size()?page.getRecords().size():pageNum*8);i++){
                VideoVO.SearchVideo showByVideoType = new VideoVO.SearchVideo();
                Video video = videos.get(i);
                if(video.getStatus()!=0) {
                    showByVideoType.setVideo_id(video.getVideoId());
                    showByVideoType.setImage_url(video.getImageUrl());
                    showByVideoType.setTitle(video.getTitle());
                    showByVideoType.setTotal_time(Long2String(video.getTotalTime()));
                    showByVideoType.setViews(video.getViews());
                    showByVideoType.setAccount(userMapper.selectById(video.getUserId()).getAccount());
                    list.add(showByVideoType);
                }
            }
            return list;
        }else {
            //ew.where("video_type={0}", videotype).like("title",search).orderBy("views", false);
            //ew.where("video_type={0}", videotype);
            page.setRecords(videoMapper.searchVideo(search,videotype));//记录page
            //List<Video> videos = videoMapper.selectPage(page, ew);
            List<Video> videos = page.getRecords();
            List<VideoVO.SearchVideo> list = new ArrayList<VideoVO.SearchVideo>();
            for (int i=(pageNum-1)*8;i<(pageNum*8>page.getRecords().size()?page.getRecords().size():pageNum*8);i++) {
                VideoVO.SearchVideo showByVideoType = new VideoVO.SearchVideo();
                Video video = videos.get(i);
                if (video.getStatus() != 0) {
                    showByVideoType.setVideo_id(video.getVideoId());
                    showByVideoType.setImage_url(video.getImageUrl());
                    showByVideoType.setTitle(video.getTitle());
                    showByVideoType.setTotal_time(Long2String(video.getTotalTime()));
                    showByVideoType.setViews(video.getViews());
                    showByVideoType.setAccount(userMapper.selectById(video.getUserId()).getAccount());
                    list.add(showByVideoType);
                }
            }
            return list;
        }
    }


    /**
     * 上传视频
     *
     * @return
     * @throws Exception
     */
    @Transactional
    public Video uploadVideo(VideoVO.UploadVideo uploadVideo) throws Exception {

        Video video = uploadVideo.getVideo();
        videoMapper.insert(video);
        return video;
    }

    /**
     * 举报无效操作
     * @param ID
     * @return
     */

    public boolean invalid(Long ID) {
        Abuse abuse=abuseMapper.selectById(ID);

        abuse.setStatus(1);
        Video video=videoMapper.selectById(abuse.getVideoId());

        video.setStatus(1);
        if(abuseMapper.updateById(abuse)!=0&&videoMapper.updateById(video)!=0){

            return true;

        }

        return false;
    }

    /**
     * 返回用户的视频数据
     *
     * @return
     * @throws Exception
     */
    public List<VideoVO.UserVideo> UserVideo(Integer pageNum,Long userid) throws Exception {
        Page<Video> page = new Page<Video>(pageNum,8);
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        ew.ne("status",0);
        ew.where("user_id={0}",userid).orderBy("upload_date",false);
        page.setRecords( videoMapper.selectPage(page,ew));//记录page
        List<Video> videos = videoMapper.selectPage(page,ew);
        List<VideoVO.UserVideo> list = new ArrayList<VideoVO.UserVideo>();
        for(int i=0;i<page.getRecords().size();i++) {
            VideoVO.UserVideo recentThreeVideo = new VideoVO.UserVideo();
            Video nowVideo = videos.get(i);
            if(nowVideo.getStatus()!=0) {
                User nowuser = userMapper.selectById(nowVideo.getUserId());
                recentThreeVideo.setVideo_id(nowVideo.getVideoId());
                recentThreeVideo.setImage_url(nowVideo.getImageUrl());
                recentThreeVideo.setTitle(nowVideo.getTitle());
                recentThreeVideo.setTotal_time(Long2String(nowVideo.getTotalTime()));
                recentThreeVideo.setViews(nowVideo.getViews());
                recentThreeVideo.setAccount(nowuser.getAccount());
                list.add(recentThreeVideo);
            }
        }
        return list;
    }

    /**
     * 返回关注的全部用户的视频数据，按上传时间排序
     *
     * @return
     * @throws Exception
     */
    public List<VideoVO.FollowVideo> FollowVideo(Integer pageNum,Long userid) throws Exception {

        Page<Video> page = new Page<Video>(pageNum,8);
        Follow follow = new Follow();
        follow.setFollowerId(userid);
        EntityWrapper<Follow> ewfollow = new EntityWrapper<Follow>();
        ewfollow.where("follower_id={0}",userid);
        List<Follow> follows = followMapper.selectList(ewfollow);
        List<Video> videos = null;
        EntityWrapper<Video> ew = new EntityWrapper<Video>();
        ew.ne("status",0);
        ew.orderBy("upload_date", false);
        for(int k=0;k<follows.size();k++) {
            Long followid = follows.get(k).getFollowId();
            if(k==0) {
                ew.where("user_id={0}", followid);
                continue;
            }
            //Page<Video> page = new Page<Video>(pageNum, 8);
//            System.out.println(followid+"sdfvgdsfvbfdbfdbdfb");
            ew.or("user_id={0}", followid);
        }
//        page.setRecords( videoMapper.selectPage(page,ew));//记录page
        videos = videoMapper.selectPage(page,ew);
        List<VideoVO.FollowVideo> list = new ArrayList<VideoVO.FollowVideo>();
        if(follows.size()==0){
            return list;
        }
        for (int i = 0; i < videos.size(); i++) {
            VideoVO.FollowVideo recentThreeVideo = new VideoVO.FollowVideo();
            Video nowVideo = videos.get(i);
            if (nowVideo.getStatus() != 0) {
                User nowuser = userMapper.selectById(nowVideo.getUserId());
                recentThreeVideo.setVideo_id(nowVideo.getVideoId());
                recentThreeVideo.setImage_url(nowVideo.getImageUrl());
                recentThreeVideo.setTitle(nowVideo.getTitle());
                recentThreeVideo.setTotal_time(Long2String(nowVideo.getTotalTime()));
                recentThreeVideo.setViews(nowVideo.getViews());
                recentThreeVideo.setAccount(nowuser.getAccount());
                list.add(recentThreeVideo);
            }
        }

        return list;
    }

    /**
     * 返回用户观看历史的视频数据，按观看时间排序
     *
     * @return
     * @throws Exception
     */
    public List<VideoVO.HistoryVideo> HistoryVideo(Long userid) throws Exception {

        if(userid>0) {
            History histories = historyMapper.selectById(userid);
            if(histories==null){
                historyMapper.insert(new History(userid,""));
                histories = historyMapper.selectById(userid);
            }
            String videos = histories.getVideos();
            //String str = "[{name:'a',value:'aa'},{name:'b',value:'bb'},{name:'c',value:'cc'},{name:'d',value:'dd'}]" ;  // 一个未转化的字符串

            List<VideoVO.HistoryVideo> list = new ArrayList<VideoVO.HistoryVideo>();
            JSONArray json = JSONArray.fromObject(videos); // 首先把字符串转成 JSONArray  对象

            if (json !=null &&json.size() > 0) {
                for (int i = 0; i < json.size(); i++) {
                    VideoVO.HistoryVideo historyVideo = new VideoVO.HistoryVideo();
                    JSONObject job = json.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                    //System.out.println(job.get("name")+"=") ;  // 得到 每个对象中的属性值
                    Long videoid = Long.parseLong(job.get("video_id").toString());
                    String time = job.get("time").toString();
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    long t = Long.parseLong(time);
                    //System.out.println(t);
                    Date date = new Date(t);


                    Video video = videoMapper.selectById(videoid);
                    if (video.getStatus() != 0) {
                        User nowuser = userMapper.selectById(video.getUserId());
                        historyVideo.setVideo_id(video.getVideoId());
                        historyVideo.setImage_url(video.getImageUrl());
                        historyVideo.setTitle(video.getTitle());
                        historyVideo.setTotal_time(Long2String(video.getTotalTime()));
                        historyVideo.setViews(video.getViews());
                        historyVideo.setAccount(nowuser.getAccount());
                        historyVideo.setTime(format.format(date));
                        list.add(historyVideo);
                    }
                }
            }
            return list;
        }else return null;
    }

    /**
     * 更新历史记录
     *
     * @return
     * @throws Exception
     */
    public boolean updateHistory(Long userid,Long videoid) throws Exception {

        if(userid>0) {
            History histories = historyMapper.selectById(userid);
            if(histories==null){
                historyMapper.insert(new History(userid,""));
                histories = historyMapper.selectById(userid);
            }
            String videos = histories.getVideos();
            JSONArray json = new JSONArray();
            if(videos!=null&&!videos.equals("")) json = JSONArray.fromObject(videos); // 首先把字符串转成 JSONArray  对象

            Map<String, String> map = new HashMap<String, String>();
            if (json.size() > 0) {
                for (int i = 0; i < json.size(); i++) {
                    JSONObject job = json.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                    map.put((String)job.get("video_id"), (String)job.get("time"));
                }
            }
            map.put(videoid.toString(), String.valueOf(new Date().getTime()));
            map = sortMapByValue(map);//根据日期进行排序
            /**把MAP写回数据库*/
            JSONArray json1 = new JSONArray();
            int count = 0;//遍历map数组到第几个
            if(json.size()>0) {
                for (int i = 0; i < json.size(); i++) {
                    JSONObject job = json.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
                    count = 0;
                    for (Map.Entry<String, String> entry : map.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue();
                        if (count == i) {
                            job.put("video_id", key);
                            job.put("time", value);
                            json1.add(job);
                            if (i == json.size() - 1 && map.size() > json.size()) {
                                i++;
                                count++;
                                continue;
                            }
                            break;
                        } else count++;
                    }
                }
            }else{
                JSONObject job = new JSONObject();
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    job.put("video_id", key);
                    job.put("time", value);
                    json1.add(job);
                }
            }
            //将json对象转化为json字符串
            //System.out.println(json1.toString());
            //videosResult = "["+videosResult+"]";
            histories.setVideos(json1.toString());
            historyMapper.updateById(histories);
        }
        return true;
    }

    public Page<Video> getVideoList(String name, int status) {
        EntityWrapper<Video> wrapper=new EntityWrapper<Video>();
        wrapper.eq("status",status).like("title","%"+name+"%");
        Page<Video> videoPage=new Page<Video>();
        videoPage.setCurrent(1);
        videoPage.setSize(8);
        videoPage.setAsc(false);
        videoPage.setOrderByField("upload_date");
        Page<Video> page= videoService.selectPage(videoPage,wrapper);
        return page;

    }
}
